import { store } from "./reducer/Index";
import { connect } from "react-redux";
import { combineReducers } from "redux";
import { injectIntl } from 'react-intl';

//派发格式

/**
 * 组件注入对应 reducer 的初始值 initState
 * @param component 组件
 * @param reducerClassTs 可注入多个reducer组件，withReducers(React组件, reducerA, reducerB ...)
 */
const withReducers = (component, ...reducerClassTs) => {
    let mapStateToProps = (state) => {
        const stateObj = {};
        reducerClassTs.forEach((item) => {
            for(let k in item.initState) {
                stateObj[k] = state[item.key][k]
            }
        })
        return stateObj
    }
    return connect(mapStateToProps, null)(component);
}

const withReducersIntl = (component, ...reducerClassTs) => {
    if(!reducerClassTs || !reducerClassTs.length){
        return injectIntl(component);
    }
    return withReducers(injectIntl(component), ...reducerClassTs)
}

/**
 * 生成 reducers，返回注入store
 * @param asyncReducers reducer的派发
 */
const makeAllReducer = (asyncReducers) => {
    return combineReducers({
        ...asyncReducers
    });
}

/**
 * reducer初始化, 后续都用这个函数初始化！！！后续都用这个函数初始化！！！后续都用这个函数初始化！！！
 * @param classReducer reducer类
 * @param storeSta 默认true，为非全局，false为全局
 */
const injectReducer = ( classReducer, storeSta = true) => {
    const obj = new classReducer();
    if(storeSta) { //动态加入
        if (Object.hasOwnProperty.call(store.asyncReducers, obj.key)) {return obj};
        store.asyncReducers[obj.key] = createReducer(obj).reducer;
        store.replaceReducer(makeAllReducer(store.asyncReducers));
    } else { //全局
        createReducer(obj)
    }
    return obj
}

/**
 * 类文件生成reducer
 * @param classReducer 类文件
 */
const createReducer = (classReducer) => {
    classReducer.reducer || (classReducer.reducer = (state = classReducer.initState, action) => {
        const handler = classReducer.actionHandlers[action.type];
        return handler ? handler(state, action) : state;
    })
    return classReducer;
}

// 全局状态的派发 = store.dispatch(actions)
const dispatch = (actions) => (store.dispatch(actions))

const getState = (classReducer) => store.getState()[classReducer.key]

export {withReducers, makeAllReducer, injectReducer, createReducer, dispatch, withReducersIntl, getState}